package durak.server.control;

import durak.common.control.GameCommand;
import durak.common.control.GameCommand.CommandType;
import durak.common.model.Card;
import durak.common.model.Cards;
import durak.common.model.GameTableState;
import durak.common.model.Hand;

public class PlayerControlAutomatic extends PlayerControl {

	private Hand hand;
	private GameTableState gameState;
	private boolean isTableFull;
	
	public PlayerControlAutomatic(Game gameSession) {
		super(gameSession);
		hand = new Hand();
		// view = new PlayerView();
		isTableFull = false;
	}

	public void handleReceivedMessageFromServer(GameCommand serverCommand) {

		switch (serverCommand.getCommandType()) {
		case S2C_NOTIFY_STATE:

			responseToNotifyState(serverCommand);
			break;
		case S2C_ATTACK:
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			responseToAttackCommand(serverCommand);
			break;

		case S2C_DEFEND:
			try {
				sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			responseToDefendCommand(serverCommand);

			break;

		case S2C_GAME_FINISHED:

			responseToGameFinishedCommand(serverCommand);

			break;

		case S2C_ROUND_FINISHED:

			responseToRoundFinishedCommand(serverCommand);

			break;

		default:
			System.out.println("Received command from server" + serverCommand.getCommandType());

			break;
		}

	}

	public void attack() {
		GameCommand command = new GameCommand(GameCommand.CommandType.S2C_ATTACK);
		handleReceivedMessageFromServer(command);
	}

	public void defend(Cards cards) {
		GameCommand command = new GameCommand(GameCommand.CommandType.S2C_DEFEND, cards);
		handleReceivedMessageFromServer(command);
	}

	private void responseToNotifyState(GameCommand serverCommand) {
		hand.setCards(serverCommand.getCards().getCards());
		gameState = serverCommand.getGameState();

	}

	public void notifyGameState(GameTableState gameState) {
		GameCommand command = new GameCommand(GameCommand.CommandType.S2C_NOTIFY_STATE);
		command.setCards(super.getPlayer().getHand());
		handleReceivedMessageFromServer(command);
	}

	private void responseToRoundFinishedCommand(GameCommand serverCommand) {
		System.out.println("Received command from server" + serverCommand.getCommandType());
		System.out.println(serverCommand.getCommandType());
	}

	private void responseToLostCommand(GameCommand serverCommand) {
		System.out.println("Received command from server" + serverCommand.getCommandType());
		System.out.println(serverCommand.getCommandType());
	}

	private void responseToGameFinishedCommand(GameCommand serverCommand) {
		System.out.println("Received command from server" + serverCommand.getCommandType());
		System.out.println(serverCommand.getCommandType());
	}

	private void responseToDefendCommand(GameCommand serverCommand) {
		System.out.println("Received command from server" + serverCommand.getCommandType());
		System.out.println(serverCommand.getCommandType());
		Cards responeToAttack = new Cards();
		System.out.println("The current hand is ");
		System.out.println(hand);
		for (Card attackCard : serverCommand.getCards())
			for (Card defendCard : hand)
				if (attackCard.getSuit().compareTo(defendCard.getSuit()) == 0 && defendCard.getRank().compareTo(attackCard.getRank()) >= 0) {
					System.out.println("going to defend with " + defendCard);
					System.out.println(defendCard);
					responeToAttack.addCard(defendCard);
					break;
				}
		if (responeToAttack.size() == serverCommand.getCards().size()) {
			GameCommand commandToServer = new GameCommand(CommandType.C2S_DEFENDED, responeToAttack);
			hand.removeCards(responeToAttack);
			super.getGameSession().getCommandHandler().handleReceivedMessageFromClient(this, commandToServer);
		} else {
			GameCommand commandToServer = new GameCommand(CommandType.C2S_WITHDRAWN);
			super.getGameSession().getCommandHandler().handleReceivedMessageFromClient(this, commandToServer);
		}

	}

	void responseToAttackCommand(GameCommand serverCommand) {

		if(isTableFull) {
			GameCommand commandToServer = new GameCommand(CommandType.C2S_PASS_ATTACK);
			super.getGameSession().getCommandHandler().handleReceivedMessageFromClient(this, commandToServer);
			isTableFull = false;
			return;
		}
		// the comp checks if there are cards on the table
		// if not - he adds his first card
		// if there are - he choose the first card to add to the attack based
		// on the ranks on the table. he finds the first available rank
		gameState = new GameTableState();
		super.getGameSession().getGamingTable().updateGameTableState(gameState);
		if (gameState.getCardsOnTheTable().isEmpty()) {
			GameCommand commandToServer = new GameCommand(CommandType.C2S_ATTACKED, hand.getFirstCard());
			hand.DrawFirstCard();
			super.getGameSession().getCommandHandler().handleReceivedMessageFromClient(this, commandToServer);
		} else {
			Cards cardsOnTable = gameState.getCardsOnTheTable().getCards();
			for (Card cardOnTable : cardsOnTable) {
				for (Card cardInHand : hand) {
					if (cardOnTable.getRank().compareTo(cardInHand.getRank()) == 0) {
						GameCommand commandToServer = new GameCommand(CommandType.C2S_ATTACKED, cardInHand);
						hand.removeCard(cardInHand);
						super.getGameSession().getCommandHandler().handleReceivedMessageFromClient(this, commandToServer);
						return;
					}
				}
			}
			GameCommand commandToServer = new GameCommand(CommandType.C2S_PASS_ATTACK);
			super.getGameSession().getCommandHandler().handleReceivedMessageFromClient(this, commandToServer);
		}
	}

	public void notifyGameTableFull() {
		isTableFull = true;
	}
	/**
	 * @return the initialized
	 */
	public synchronized boolean isInitialized() {
		return true;
	}

	/**
	 * @param initialized the initialized to set
	 */
	public synchronized void setInitialized(boolean initialized) {}
}
